//===----------------------------------------------------------------------===//
//
// This source file is part of the Soto for AWS open source project
//
// Copyright (c) 2017-2024 the Soto project authors
// Licensed under Apache License v2.0
//
// See LICENSE.txt for license information
// See CONTRIBUTORS.txt for the list of Soto project authors
//
// SPDX-License-Identifier: Apache-2.0
//
//===----------------------------------------------------------------------===//

// THIS FILE IS AUTOMATICALLY GENERATED by https://github.com/soto-project/soto-codegenerator.
// DO NOT EDIT.

#if canImport(FoundationEssentials)
import FoundationEssentials
#else
import Foundation
#endif
@_spi(SotoInternal) import SotoCore

extension ControlCatalog {
    // MARK: Enums

    public enum ControlBehavior: String, CustomStringConvertible, Codable, Sendable, CodingKeyRepresentable {
        case detective = "DETECTIVE"
        case preventive = "PREVENTIVE"
        case proactive = "PROACTIVE"
        public var description: String { return self.rawValue }
    }

    public enum ControlScope: String, CustomStringConvertible, Codable, Sendable, CodingKeyRepresentable {
        case global = "GLOBAL"
        case regional = "REGIONAL"
        public var description: String { return self.rawValue }
    }

    public enum ControlSeverity: String, CustomStringConvertible, Codable, Sendable, CodingKeyRepresentable {
        case critical = "CRITICAL"
        case high = "HIGH"
        case low = "LOW"
        case medium = "MEDIUM"
        public var description: String { return self.rawValue }
    }

    public enum MappingType: String, CustomStringConvertible, Codable, Sendable, CodingKeyRepresentable {
        case commonControl = "COMMON_CONTROL"
        case framework = "FRAMEWORK"
        public var description: String { return self.rawValue }
    }

    public enum Mapping: AWSDecodableShape, Sendable {
        /// The common control mapping details when the mapping type relates to a common control.
        case commonControl(CommonControlMappingDetails)
        /// The framework mapping details when the mapping type relates to a compliance framework.
        case framework(FrameworkMappingDetails)

        public init(from decoder: Decoder) throws {
            let container = try decoder.container(keyedBy: CodingKeys.self)
            guard container.allKeys.count == 1, let key = container.allKeys.first else {
                let context = DecodingError.Context(
                    codingPath: container.codingPath,
                    debugDescription: "Expected exactly one key, but got \(container.allKeys.count)"
                )
                throw DecodingError.dataCorrupted(context)
            }
            switch key {
            case .commonControl:
                let value = try container.decode(CommonControlMappingDetails.self, forKey: .commonControl)
                self = .commonControl(value)
            case .framework:
                let value = try container.decode(FrameworkMappingDetails.self, forKey: .framework)
                self = .framework(value)
            }
        }

        private enum CodingKeys: String, CodingKey {
            case commonControl = "CommonControl"
            case framework = "Framework"
        }
    }

    // MARK: Shapes

    public struct AssociatedDomainSummary: AWSDecodableShape {
        /// The Amazon Resource Name (ARN) of the related domain.
        public let arn: String?
        /// The name of the related domain.
        public let name: String?

        @inlinable
        public init(arn: String? = nil, name: String? = nil) {
            self.arn = arn
            self.name = name
        }

        private enum CodingKeys: String, CodingKey {
            case arn = "Arn"
            case name = "Name"
        }
    }

    public struct AssociatedObjectiveSummary: AWSDecodableShape {
        /// The Amazon Resource Name (ARN) of the related objective.
        public let arn: String?
        /// The name of the related objective.
        public let name: String?

        @inlinable
        public init(arn: String? = nil, name: String? = nil) {
            self.arn = arn
            self.name = name
        }

        private enum CodingKeys: String, CodingKey {
            case arn = "Arn"
            case name = "Name"
        }
    }

    public struct CommonControlFilter: AWSEncodableShape {
        /// The objective that's used as filter criteria. You can use this parameter to specify one objective ARN at a time. Passing multiple ARNs in the CommonControlFilter isn’t supported.
        public let objectives: [ObjectiveResourceFilter]?

        @inlinable
        public init(objectives: [ObjectiveResourceFilter]? = nil) {
            self.objectives = objectives
        }

        public func validate(name: String) throws {
            try self.objectives?.forEach {
                try $0.validate(name: "\(name).objectives[]")
            }
        }

        private enum CodingKeys: String, CodingKey {
            case objectives = "Objectives"
        }
    }

    public struct CommonControlMappingDetails: AWSDecodableShape {
        /// The Amazon Resource Name (ARN) that identifies the common control in the mapping.
        public let commonControlArn: String

        @inlinable
        public init(commonControlArn: String) {
            self.commonControlArn = commonControlArn
        }

        private enum CodingKeys: String, CodingKey {
            case commonControlArn = "CommonControlArn"
        }
    }

    public struct CommonControlSummary: AWSDecodableShape {
        /// The Amazon Resource Name (ARN) that identifies the common control.
        public let arn: String
        /// The time when the common control was created.
        public let createTime: Date
        /// The description of the common control.
        public let description: String
        /// The domain that the common control belongs to.
        public let domain: AssociatedDomainSummary
        /// The time when the common control was most recently updated.
        public let lastUpdateTime: Date
        /// The name of the common control.
        public let name: String
        /// The objective that the common control belongs to.
        public let objective: AssociatedObjectiveSummary

        @inlinable
        public init(arn: String, createTime: Date, description: String, domain: AssociatedDomainSummary, lastUpdateTime: Date, name: String, objective: AssociatedObjectiveSummary) {
            self.arn = arn
            self.createTime = createTime
            self.description = description
            self.domain = domain
            self.lastUpdateTime = lastUpdateTime
            self.name = name
            self.objective = objective
        }

        private enum CodingKeys: String, CodingKey {
            case arn = "Arn"
            case createTime = "CreateTime"
            case description = "Description"
            case domain = "Domain"
            case lastUpdateTime = "LastUpdateTime"
            case name = "Name"
            case objective = "Objective"
        }
    }

    public struct ControlFilter: AWSEncodableShape {
        /// A filter that narrows the results to controls with specific implementation types or identifiers. This field allows you to find controls that are implemented by specific Amazon Web Services services or with specific service identifiers.
        public let implementations: ImplementationFilter?

        @inlinable
        public init(implementations: ImplementationFilter? = nil) {
            self.implementations = implementations
        }

        public func validate(name: String) throws {
            try self.implementations?.validate(name: "\(name).implementations")
        }

        private enum CodingKeys: String, CodingKey {
            case implementations = "Implementations"
        }
    }

    public struct ControlMapping: AWSDecodableShape {
        /// The Amazon Resource Name (ARN) that identifies the control in the mapping.
        public let controlArn: String
        /// The details of the mapping relationship, containing either framework or common control information.
        public let mapping: Mapping
        /// The type of mapping relationship between the control and other entities. Indicates whether the mapping is to a framework or common control.
        public let mappingType: MappingType

        @inlinable
        public init(controlArn: String, mapping: Mapping, mappingType: MappingType) {
            self.controlArn = controlArn
            self.mapping = mapping
            self.mappingType = mappingType
        }

        private enum CodingKeys: String, CodingKey {
            case controlArn = "ControlArn"
            case mapping = "Mapping"
            case mappingType = "MappingType"
        }
    }

    public struct ControlMappingFilter: AWSEncodableShape {
        /// A list of common control ARNs to filter the mappings. When specified, only mappings associated with these common controls are returned.
        public let commonControlArns: [String]?
        /// A list of control ARNs to filter the mappings. When specified, only mappings associated with these controls are returned.
        public let controlArns: [String]?
        /// A list of mapping types to filter the mappings. When specified, only mappings of these types are returned.
        public let mappingTypes: [MappingType]?

        @inlinable
        public init(commonControlArns: [String]? = nil, controlArns: [String]? = nil, mappingTypes: [MappingType]? = nil) {
            self.commonControlArns = commonControlArns
            self.controlArns = controlArns
            self.mappingTypes = mappingTypes
        }

        public func validate(name: String) throws {
            try self.commonControlArns?.forEach {
                try validate($0, name: "commonControlArns[]", parent: name, max: 2048)
                try validate($0, name: "commonControlArns[]", parent: name, min: 41)
                try validate($0, name: "commonControlArns[]", parent: name, pattern: "^arn:(aws(?:[-a-z]*)?):controlcatalog:::common-control/[0-9a-z]+$")
            }
            try self.validate(self.commonControlArns, name: "commonControlArns", parent: name, max: 1)
            try self.validate(self.commonControlArns, name: "commonControlArns", parent: name, min: 1)
            try self.controlArns?.forEach {
                try validate($0, name: "controlArns[]", parent: name, max: 2048)
                try validate($0, name: "controlArns[]", parent: name, min: 34)
                try validate($0, name: "controlArns[]", parent: name, pattern: "^arn:(aws(?:[-a-z]*)?):(controlcatalog|controltower):[a-zA-Z0-9-]*::control/[0-9a-zA-Z_\\-]+$")
            }
            try self.validate(self.controlArns, name: "controlArns", parent: name, max: 1)
            try self.validate(self.controlArns, name: "controlArns", parent: name, min: 1)
            try self.validate(self.mappingTypes, name: "mappingTypes", parent: name, max: 1)
            try self.validate(self.mappingTypes, name: "mappingTypes", parent: name, min: 1)
        }

        private enum CodingKeys: String, CodingKey {
            case commonControlArns = "CommonControlArns"
            case controlArns = "ControlArns"
            case mappingTypes = "MappingTypes"
        }
    }

    public struct ControlParameter: AWSDecodableShape {
        /// The parameter name. This name is the parameter key when you call  EnableControl  or  UpdateEnabledControl .
        public let name: String

        @inlinable
        public init(name: String) {
            self.name = name
        }

        private enum CodingKeys: String, CodingKey {
            case name = "Name"
        }
    }

    public struct ControlSummary: AWSDecodableShape {
        /// A list of alternative identifiers for the control. These are human-readable designators, such as SH.S3.1. Several aliases can refer to the same control across different Amazon Web Services services or compliance frameworks.
        public let aliases: [String]?
        /// The Amazon Resource Name (ARN) of the control.
        public let arn: String
        /// An enumerated type, with the following possible values:
        public let behavior: ControlBehavior?
        /// A timestamp that notes the time when the control was released (start of its life) as a governance capability in Amazon Web Services.
        public let createTime: Date?
        /// A description of the control, as it may appear in the console. Describes the functionality of the control.
        public let description: String
        /// A list of Amazon Web Services resource types that are governed by this control. This information helps you understand which controls can govern certain types of resources, and conversely, which resources are affected when the control is implemented. The resources are represented as Amazon Web Services CloudFormation resource types. If GovernedResources cannot be represented by available CloudFormation resource types, it’s returned as an empty list.
        public let governedResources: [String]?
        /// An object of type ImplementationSummary that describes how the control is implemented.
        public let implementation: ImplementationSummary?
        /// The display name of the control.
        public let name: String
        /// An enumerated type, with the following possible values:
        public let severity: ControlSeverity?

        @inlinable
        public init(aliases: [String]? = nil, arn: String, behavior: ControlBehavior? = nil, createTime: Date? = nil, description: String, governedResources: [String]? = nil, implementation: ImplementationSummary? = nil, name: String, severity: ControlSeverity? = nil) {
            self.aliases = aliases
            self.arn = arn
            self.behavior = behavior
            self.createTime = createTime
            self.description = description
            self.governedResources = governedResources
            self.implementation = implementation
            self.name = name
            self.severity = severity
        }

        private enum CodingKeys: String, CodingKey {
            case aliases = "Aliases"
            case arn = "Arn"
            case behavior = "Behavior"
            case createTime = "CreateTime"
            case description = "Description"
            case governedResources = "GovernedResources"
            case implementation = "Implementation"
            case name = "Name"
            case severity = "Severity"
        }
    }

    public struct DomainResourceFilter: AWSEncodableShape {
        /// The Amazon Resource Name (ARN) of the domain.
        public let arn: String?

        @inlinable
        public init(arn: String? = nil) {
            self.arn = arn
        }

        public func validate(name: String) throws {
            try self.validate(self.arn, name: "arn", parent: name, max: 2048)
            try self.validate(self.arn, name: "arn", parent: name, min: 33)
            try self.validate(self.arn, name: "arn", parent: name, pattern: "^arn:(aws(?:[-a-z]*)?):controlcatalog:::domain/[0-9a-z]+$")
        }

        private enum CodingKeys: String, CodingKey {
            case arn = "Arn"
        }
    }

    public struct DomainSummary: AWSDecodableShape {
        /// The Amazon Resource Name (ARN) that identifies the domain.
        public let arn: String
        /// The time when the domain was created.
        public let createTime: Date
        /// The description of the domain.
        public let description: String
        /// The time when the domain was most recently updated.
        public let lastUpdateTime: Date
        /// The name of the domain.
        public let name: String

        @inlinable
        public init(arn: String, createTime: Date, description: String, lastUpdateTime: Date, name: String) {
            self.arn = arn
            self.createTime = createTime
            self.description = description
            self.lastUpdateTime = lastUpdateTime
            self.name = name
        }

        private enum CodingKeys: String, CodingKey {
            case arn = "Arn"
            case createTime = "CreateTime"
            case description = "Description"
            case lastUpdateTime = "LastUpdateTime"
            case name = "Name"
        }
    }

    public struct FrameworkMappingDetails: AWSDecodableShape {
        /// The specific item or requirement within the framework that the control maps to.
        public let item: String
        /// The name of the compliance framework that the control maps to.
        public let name: String

        @inlinable
        public init(item: String, name: String) {
            self.item = item
            self.name = name
        }

        private enum CodingKeys: String, CodingKey {
            case item = "Item"
            case name = "Name"
        }
    }

    public struct GetControlRequest: AWSEncodableShape {
        /// The Amazon Resource Name (ARN) of the control. It has one of the following formats:  Global format   arn:{PARTITION}:controlcatalog:::control/{CONTROL_CATALOG_OPAQUE_ID}   Or Regional format   arn:{PARTITION}:controltower:{REGION}::control/{CONTROL_TOWER_OPAQUE_ID}  Here is a more general pattern that covers Amazon Web Services Control Tower and Control Catalog ARNs:  ^arn:(aws(?:[-a-z]*)?):(controlcatalog|controltower):[a-zA-Z0-9-]*::control/[0-9a-zA-Z_\\-]+$
        public let controlArn: String

        @inlinable
        public init(controlArn: String) {
            self.controlArn = controlArn
        }

        public func validate(name: String) throws {
            try self.validate(self.controlArn, name: "controlArn", parent: name, max: 2048)
            try self.validate(self.controlArn, name: "controlArn", parent: name, min: 34)
            try self.validate(self.controlArn, name: "controlArn", parent: name, pattern: "^arn:(aws(?:[-a-z]*)?):(controlcatalog|controltower):[a-zA-Z0-9-]*::control/[0-9a-zA-Z_\\-]+$")
        }

        private enum CodingKeys: String, CodingKey {
            case controlArn = "ControlArn"
        }
    }

    public struct GetControlResponse: AWSDecodableShape {
        /// A list of alternative identifiers for the control. These are human-readable designators, such as SH.S3.1. Several aliases can refer to the same control across different Amazon Web Services services or compliance frameworks.
        public let aliases: [String]?
        /// The Amazon Resource Name (ARN) of the control.
        public let arn: String
        /// A term that identifies the control's functional behavior. One of Preventive, Detective, Proactive
        public let behavior: ControlBehavior
        /// A timestamp that notes the time when the control was released (start of its life) as a governance capability in Amazon Web Services.
        public let createTime: Date?
        /// A description of what the control does.
        public let description: String
        /// A list of Amazon Web Services resource types that are governed by this control. This information helps you understand which controls can govern certain types of resources, and conversely, which resources are affected when the control is implemented. The resources are represented as Amazon Web Services CloudFormation resource types. If GovernedResources cannot be represented by available CloudFormation resource types, it’s returned as an empty list.
        public let governedResources: [String]?
        /// Returns information about the control, as an ImplementationDetails object that shows the underlying implementation type for a control.
        public let implementation: ImplementationDetails?
        /// The display name of the control.
        public let name: String
        /// Returns an array of ControlParameter objects that specify the parameters a control supports. An empty list is returned for controls that don’t support parameters.
        public let parameters: [ControlParameter]?
        public let regionConfiguration: RegionConfiguration
        /// An enumerated type, with the following possible values:
        public let severity: ControlSeverity?

        @inlinable
        public init(aliases: [String]? = nil, arn: String, behavior: ControlBehavior, createTime: Date? = nil, description: String, governedResources: [String]? = nil, implementation: ImplementationDetails? = nil, name: String, parameters: [ControlParameter]? = nil, regionConfiguration: RegionConfiguration, severity: ControlSeverity? = nil) {
            self.aliases = aliases
            self.arn = arn
            self.behavior = behavior
            self.createTime = createTime
            self.description = description
            self.governedResources = governedResources
            self.implementation = implementation
            self.name = name
            self.parameters = parameters
            self.regionConfiguration = regionConfiguration
            self.severity = severity
        }

        private enum CodingKeys: String, CodingKey {
            case aliases = "Aliases"
            case arn = "Arn"
            case behavior = "Behavior"
            case createTime = "CreateTime"
            case description = "Description"
            case governedResources = "GovernedResources"
            case implementation = "Implementation"
            case name = "Name"
            case parameters = "Parameters"
            case regionConfiguration = "RegionConfiguration"
            case severity = "Severity"
        }
    }

    public struct ImplementationDetails: AWSDecodableShape {
        /// A service-specific identifier for the control, assigned by the service that implemented the control. For example, this identifier could be an Amazon Web Services Config Rule ID or a Security Hub Control ID.
        public let identifier: String?
        /// A string that describes a control's implementation type.
        public let type: String

        @inlinable
        public init(identifier: String? = nil, type: String) {
            self.identifier = identifier
            self.type = type
        }

        private enum CodingKeys: String, CodingKey {
            case identifier = "Identifier"
            case type = "Type"
        }
    }

    public struct ImplementationFilter: AWSEncodableShape {
        /// A list of service-specific identifiers that can serve as filters. For example, you can filter for controls with specific Amazon Web Services Config Rule IDs or Security Hub Control IDs.
        public let identifiers: [String]?
        /// A list of implementation types that can serve as filters. For example, you can filter for controls implemented as Amazon Web Services Config Rules by specifying AWS::Config::ConfigRule as a type.
        public let types: [String]?

        @inlinable
        public init(identifiers: [String]? = nil, types: [String]? = nil) {
            self.identifiers = identifiers
            self.types = types
        }

        public func validate(name: String) throws {
            try self.identifiers?.forEach {
                try validate($0, name: "identifiers[]", parent: name, max: 256)
                try validate($0, name: "identifiers[]", parent: name, min: 1)
                try validate($0, name: "identifiers[]", parent: name, pattern: "^[a-zA-Z0-9_\\.-]+$")
            }
            try self.validate(self.identifiers, name: "identifiers", parent: name, max: 1)
            try self.validate(self.identifiers, name: "identifiers", parent: name, min: 1)
            try self.types?.forEach {
                try validate($0, name: "types[]", parent: name, max: 2048)
                try validate($0, name: "types[]", parent: name, min: 7)
                try validate($0, name: "types[]", parent: name, pattern: "^[A-Za-z0-9]+(::[A-Za-z0-9_]+){2,3}$")
            }
            try self.validate(self.types, name: "types", parent: name, max: 1)
            try self.validate(self.types, name: "types", parent: name, min: 1)
        }

        private enum CodingKeys: String, CodingKey {
            case identifiers = "Identifiers"
            case types = "Types"
        }
    }

    public struct ImplementationSummary: AWSDecodableShape {
        /// The identifier originally assigned by the Amazon Web Services service that implements the control. For example, CODEPIPELINE_DEPLOYMENT_COUNT_CHECK.
        public let identifier: String?
        /// A string that represents the Amazon Web Services service that implements this control. For example, a value of AWS::Config::ConfigRule indicates that the control is implemented by Amazon Web Services Config, and AWS::SecurityHub::SecurityControl indicates implementation by Amazon Web Services Security Hub.
        public let type: String

        @inlinable
        public init(identifier: String? = nil, type: String) {
            self.identifier = identifier
            self.type = type
        }

        private enum CodingKeys: String, CodingKey {
            case identifier = "Identifier"
            case type = "Type"
        }
    }

    public struct ListCommonControlsRequest: AWSEncodableShape {
        /// An optional filter that narrows the results to a specific objective. This filter allows you to specify one objective ARN at a time. Passing multiple ARNs in the CommonControlFilter isn’t supported.
        public let commonControlFilter: CommonControlFilter?
        /// The maximum number of results on a page or for an API request call.
        public let maxResults: Int?
        /// The pagination token that's used to fetch the next set of results.
        public let nextToken: String?

        @inlinable
        public init(commonControlFilter: CommonControlFilter? = nil, maxResults: Int? = nil, nextToken: String? = nil) {
            self.commonControlFilter = commonControlFilter
            self.maxResults = maxResults
            self.nextToken = nextToken
        }

        public func encode(to encoder: Encoder) throws {
            let request = encoder.userInfo[.awsRequest]! as! RequestEncodingContainer
            var container = encoder.container(keyedBy: CodingKeys.self)
            try container.encodeIfPresent(self.commonControlFilter, forKey: .commonControlFilter)
            request.encodeQuery(self.maxResults, key: "maxResults")
            request.encodeQuery(self.nextToken, key: "nextToken")
        }

        public func validate(name: String) throws {
            try self.commonControlFilter?.validate(name: "\(name).commonControlFilter")
            try self.validate(self.maxResults, name: "maxResults", parent: name, max: 100)
            try self.validate(self.maxResults, name: "maxResults", parent: name, min: 1)
            try self.validate(self.nextToken, name: "nextToken", parent: name, max: 1024)
        }

        private enum CodingKeys: String, CodingKey {
            case commonControlFilter = "CommonControlFilter"
        }
    }

    public struct ListCommonControlsResponse: AWSDecodableShape {
        /// The list of common controls that the ListCommonControls API returns.
        public let commonControls: [CommonControlSummary]
        /// The pagination token that's used to fetch the next set of results.
        public let nextToken: String?

        @inlinable
        public init(commonControls: [CommonControlSummary], nextToken: String? = nil) {
            self.commonControls = commonControls
            self.nextToken = nextToken
        }

        private enum CodingKeys: String, CodingKey {
            case commonControls = "CommonControls"
            case nextToken = "NextToken"
        }
    }

    public struct ListControlMappingsRequest: AWSEncodableShape {
        /// An optional filter that narrows the results to specific control mappings based on control ARNs, common control ARNs, or mapping types.
        public let filter: ControlMappingFilter?
        /// The maximum number of results on a page or for an API request call.
        public let maxResults: Int?
        /// The pagination token that's used to fetch the next set of results.
        public let nextToken: String?

        @inlinable
        public init(filter: ControlMappingFilter? = nil, maxResults: Int? = nil, nextToken: String? = nil) {
            self.filter = filter
            self.maxResults = maxResults
            self.nextToken = nextToken
        }

        public func encode(to encoder: Encoder) throws {
            let request = encoder.userInfo[.awsRequest]! as! RequestEncodingContainer
            var container = encoder.container(keyedBy: CodingKeys.self)
            try container.encodeIfPresent(self.filter, forKey: .filter)
            request.encodeQuery(self.maxResults, key: "maxResults")
            request.encodeQuery(self.nextToken, key: "nextToken")
        }

        public func validate(name: String) throws {
            try self.filter?.validate(name: "\(name).filter")
            try self.validate(self.maxResults, name: "maxResults", parent: name, max: 1000)
            try self.validate(self.maxResults, name: "maxResults", parent: name, min: 1)
            try self.validate(self.nextToken, name: "nextToken", parent: name, max: 1024)
        }

        private enum CodingKeys: String, CodingKey {
            case filter = "Filter"
        }
    }

    public struct ListControlMappingsResponse: AWSDecodableShape {
        /// The list of control mappings that the ListControlMappings API returns.
        public let controlMappings: [ControlMapping]
        /// The pagination token that's used to fetch the next set of results.
        public let nextToken: String?

        @inlinable
        public init(controlMappings: [ControlMapping], nextToken: String? = nil) {
            self.controlMappings = controlMappings
            self.nextToken = nextToken
        }

        private enum CodingKeys: String, CodingKey {
            case controlMappings = "ControlMappings"
            case nextToken = "NextToken"
        }
    }

    public struct ListControlsRequest: AWSEncodableShape {
        /// An optional filter that narrows the results to controls with specific implementation types or identifiers. If you don't provide a filter, the operation returns all available controls.
        public let filter: ControlFilter?
        /// The maximum number of results on a page or for an API request call.
        public let maxResults: Int?
        /// The pagination token that's used to fetch the next set of results.
        public let nextToken: String?

        @inlinable
        public init(filter: ControlFilter? = nil, maxResults: Int? = nil, nextToken: String? = nil) {
            self.filter = filter
            self.maxResults = maxResults
            self.nextToken = nextToken
        }

        public func encode(to encoder: Encoder) throws {
            let request = encoder.userInfo[.awsRequest]! as! RequestEncodingContainer
            var container = encoder.container(keyedBy: CodingKeys.self)
            try container.encodeIfPresent(self.filter, forKey: .filter)
            request.encodeQuery(self.maxResults, key: "maxResults")
            request.encodeQuery(self.nextToken, key: "nextToken")
        }

        public func validate(name: String) throws {
            try self.filter?.validate(name: "\(name).filter")
            try self.validate(self.maxResults, name: "maxResults", parent: name, max: 100)
            try self.validate(self.maxResults, name: "maxResults", parent: name, min: 1)
            try self.validate(self.nextToken, name: "nextToken", parent: name, max: 1024)
        }

        private enum CodingKeys: String, CodingKey {
            case filter = "Filter"
        }
    }

    public struct ListControlsResponse: AWSDecodableShape {
        /// Returns a list of controls, given as structures of type controlSummary.
        public let controls: [ControlSummary]
        /// The pagination token that's used to fetch the next set of results.
        public let nextToken: String?

        @inlinable
        public init(controls: [ControlSummary], nextToken: String? = nil) {
            self.controls = controls
            self.nextToken = nextToken
        }

        private enum CodingKeys: String, CodingKey {
            case controls = "Controls"
            case nextToken = "NextToken"
        }
    }

    public struct ListDomainsRequest: AWSEncodableShape {
        /// The maximum number of results on a page or for an API request call.
        public let maxResults: Int?
        /// The pagination token that's used to fetch the next set of results.
        public let nextToken: String?

        @inlinable
        public init(maxResults: Int? = nil, nextToken: String? = nil) {
            self.maxResults = maxResults
            self.nextToken = nextToken
        }

        public func encode(to encoder: Encoder) throws {
            let request = encoder.userInfo[.awsRequest]! as! RequestEncodingContainer
            _ = encoder.container(keyedBy: CodingKeys.self)
            request.encodeQuery(self.maxResults, key: "maxResults")
            request.encodeQuery(self.nextToken, key: "nextToken")
        }

        public func validate(name: String) throws {
            try self.validate(self.maxResults, name: "maxResults", parent: name, max: 100)
            try self.validate(self.maxResults, name: "maxResults", parent: name, min: 1)
            try self.validate(self.nextToken, name: "nextToken", parent: name, max: 1024)
        }

        private enum CodingKeys: CodingKey {}
    }

    public struct ListDomainsResponse: AWSDecodableShape {
        /// The list of domains that the ListDomains API returns.
        public let domains: [DomainSummary]
        /// The pagination token that's used to fetch the next set of results.
        public let nextToken: String?

        @inlinable
        public init(domains: [DomainSummary], nextToken: String? = nil) {
            self.domains = domains
            self.nextToken = nextToken
        }

        private enum CodingKeys: String, CodingKey {
            case domains = "Domains"
            case nextToken = "NextToken"
        }
    }

    public struct ListObjectivesRequest: AWSEncodableShape {
        /// The maximum number of results on a page or for an API request call.
        public let maxResults: Int?
        /// The pagination token that's used to fetch the next set of results.
        public let nextToken: String?
        /// An optional filter that narrows the results to a specific domain. This filter allows you to specify one domain ARN at a time. Passing multiple ARNs in the ObjectiveFilter isn’t supported.
        public let objectiveFilter: ObjectiveFilter?

        @inlinable
        public init(maxResults: Int? = nil, nextToken: String? = nil, objectiveFilter: ObjectiveFilter? = nil) {
            self.maxResults = maxResults
            self.nextToken = nextToken
            self.objectiveFilter = objectiveFilter
        }

        public func encode(to encoder: Encoder) throws {
            let request = encoder.userInfo[.awsRequest]! as! RequestEncodingContainer
            var container = encoder.container(keyedBy: CodingKeys.self)
            request.encodeQuery(self.maxResults, key: "maxResults")
            request.encodeQuery(self.nextToken, key: "nextToken")
            try container.encodeIfPresent(self.objectiveFilter, forKey: .objectiveFilter)
        }

        public func validate(name: String) throws {
            try self.validate(self.maxResults, name: "maxResults", parent: name, max: 100)
            try self.validate(self.maxResults, name: "maxResults", parent: name, min: 1)
            try self.validate(self.nextToken, name: "nextToken", parent: name, max: 1024)
            try self.objectiveFilter?.validate(name: "\(name).objectiveFilter")
        }

        private enum CodingKeys: String, CodingKey {
            case objectiveFilter = "ObjectiveFilter"
        }
    }

    public struct ListObjectivesResponse: AWSDecodableShape {
        /// The pagination token that's used to fetch the next set of results.
        public let nextToken: String?
        /// The list of objectives that the ListObjectives API returns.
        public let objectives: [ObjectiveSummary]

        @inlinable
        public init(nextToken: String? = nil, objectives: [ObjectiveSummary]) {
            self.nextToken = nextToken
            self.objectives = objectives
        }

        private enum CodingKeys: String, CodingKey {
            case nextToken = "NextToken"
            case objectives = "Objectives"
        }
    }

    public struct ObjectiveFilter: AWSEncodableShape {
        /// The domain that's used as filter criteria. You can use this parameter to specify one domain ARN at a time. Passing multiple ARNs in the ObjectiveFilter isn’t supported.
        public let domains: [DomainResourceFilter]?

        @inlinable
        public init(domains: [DomainResourceFilter]? = nil) {
            self.domains = domains
        }

        public func validate(name: String) throws {
            try self.domains?.forEach {
                try $0.validate(name: "\(name).domains[]")
            }
        }

        private enum CodingKeys: String, CodingKey {
            case domains = "Domains"
        }
    }

    public struct ObjectiveResourceFilter: AWSEncodableShape {
        /// The Amazon Resource Name (ARN) of the objective.
        public let arn: String?

        @inlinable
        public init(arn: String? = nil) {
            self.arn = arn
        }

        public func validate(name: String) throws {
            try self.validate(self.arn, name: "arn", parent: name, max: 2048)
            try self.validate(self.arn, name: "arn", parent: name, min: 36)
            try self.validate(self.arn, name: "arn", parent: name, pattern: "^arn:(aws(?:[-a-z]*)?):controlcatalog:::objective/[0-9a-z]+$")
        }

        private enum CodingKeys: String, CodingKey {
            case arn = "Arn"
        }
    }

    public struct ObjectiveSummary: AWSDecodableShape {
        /// The Amazon Resource Name (ARN) that identifies the objective.
        public let arn: String
        /// The time when the objective was created.
        public let createTime: Date
        /// The description of the objective.
        public let description: String
        /// The domain that the objective belongs to.
        public let domain: AssociatedDomainSummary
        /// The time when the objective was most recently updated.
        public let lastUpdateTime: Date
        /// The name of the objective.
        public let name: String

        @inlinable
        public init(arn: String, createTime: Date, description: String, domain: AssociatedDomainSummary, lastUpdateTime: Date, name: String) {
            self.arn = arn
            self.createTime = createTime
            self.description = description
            self.domain = domain
            self.lastUpdateTime = lastUpdateTime
            self.name = name
        }

        private enum CodingKeys: String, CodingKey {
            case arn = "Arn"
            case createTime = "CreateTime"
            case description = "Description"
            case domain = "Domain"
            case lastUpdateTime = "LastUpdateTime"
            case name = "Name"
        }
    }

    public struct RegionConfiguration: AWSDecodableShape {
        /// Regions in which the control is available to be deployed.
        public let deployableRegions: [String]?
        /// The coverage of the control, if deployed. Scope is an enumerated type, with value Regional, or Global. A control with Global scope is effective in all Amazon Web Services Regions, regardless of the Region from which it is enabled, or to which it is deployed. A control implemented by an SCP is usually Global in scope. A control with Regional scope has operations that are restricted specifically to the Region from which it is enabled and to which it is deployed. Controls implemented by Config rules and CloudFormation hooks usually are Regional in scope. Security Hub controls usually are Regional in scope.
        public let scope: ControlScope

        @inlinable
        public init(deployableRegions: [String]? = nil, scope: ControlScope) {
            self.deployableRegions = deployableRegions
            self.scope = scope
        }

        private enum CodingKeys: String, CodingKey {
            case deployableRegions = "DeployableRegions"
            case scope = "Scope"
        }
    }
}

// MARK: - Errors

/// Error enum for ControlCatalog
public struct ControlCatalogErrorType: AWSErrorType {
    enum Code: String {
        case accessDeniedException = "AccessDeniedException"
        case internalServerException = "InternalServerException"
        case resourceNotFoundException = "ResourceNotFoundException"
        case throttlingException = "ThrottlingException"
        case validationException = "ValidationException"
    }

    private let error: Code
    public let context: AWSErrorContext?

    /// initialize ControlCatalog
    public init?(errorCode: String, context: AWSErrorContext) {
        guard let error = Code(rawValue: errorCode) else { return nil }
        self.error = error
        self.context = context
    }

    internal init(_ error: Code) {
        self.error = error
        self.context = nil
    }

    /// return error code string
    public var errorCode: String { self.error.rawValue }

    /// You do not have sufficient access to perform this action.
    public static var accessDeniedException: Self { .init(.accessDeniedException) }
    /// An internal service error occurred during the processing of your request. Try again later.
    public static var internalServerException: Self { .init(.internalServerException) }
    /// The requested resource does not exist.
    public static var resourceNotFoundException: Self { .init(.resourceNotFoundException) }
    /// The request was denied due to request throttling.
    public static var throttlingException: Self { .init(.throttlingException) }
    /// The request has invalid or missing parameters.
    public static var validationException: Self { .init(.validationException) }
}

extension ControlCatalogErrorType: Equatable {
    public static func == (lhs: ControlCatalogErrorType, rhs: ControlCatalogErrorType) -> Bool {
        lhs.error == rhs.error
    }
}

extension ControlCatalogErrorType: CustomStringConvertible {
    public var description: String {
        return "\(self.error.rawValue): \(self.message ?? "")"
    }
}
